<script setup lang="ts">
import { Form } from '@/components/Form'
import { useForm } from '@/hooks/web/useForm'
import { PropType, reactive, watch, ref, nextTick } from 'vue'
import { FormSchema } from '@/types/form'
import { RoleData, RoleMenuData } from "@/api/auth/role/types";
import { ElCheckboxGroup, ElCheckbox, ElCollapse, ElCollapseItem } from "element-plus";
import { getPermission } from "@/api/auth/role/index";

const props = defineProps({
  currentRow: {
    type: Object as PropType<Nullable<RoleData>>,
    default: () => null
  },
  formSchema: {
    type: Array as PropType<FormSchema[]>,
    default: () => []
  },
  actionType: {
    type: String,
    default: () => "7"
  }
})

const rules = reactive({})

const { register, methods, elFormRef } = useForm({
  schema: props.formSchema
})

watch(
  () => props.currentRow,
  (currentRow) => {
    if (!currentRow) return
    const { setValues } = methods
    setValues(currentRow)
  },
  {
    deep: true,
    immediate: true
  }
)

const handleParentCheckedChange = (menu: RoleMenuData) => {
  const allChildrenId = menu.children ? menu.children.map(m => m.id) : [];
  menu.checkedChildren = menu.checked ? allChildrenId : []
}

const handleChildrenChanged = (menu: RoleMenuData) => {
  if (menu.checkedChildren && menu.checkedChildren.length > 0) {
    menu.checked = menu.checkedChildren.length === menu.children?.length;
  } else {
    menu.checked = false;
  }
}

const menuData = ref([] as RoleMenuData[]);
const permission = ref([] as number[]);

const getCheckedMenu = () => {
  const result: number[] = [];
  menuData.value.forEach(menu => {
    if (menu.checkedChildren && menu.checkedChildren.length > 0) {
      result.push(menu.id);
      result.push(...menu.checkedChildren);
    }
  });
  return result;
}
let paramId = props.actionType == 'edit' ? props.currentRow?.id : 0
if (paramId === undefined) paramId = 0
getPermission(paramId).then(async res => {
  menuData.value = res.data.menus;
  permission.value = res.data.permission;
  await nextTick()
  if(props.actionType == 'edit' && permission.value.length > 0) {
    toSetChecked(menuData.value);
  }
});

const toSetChecked = (menuList: RoleMenuData[]) => {
  for(let menu of menuList) {
    if(menu.children && menu.children.length > 0) {
      for(let cm of menu.children) {
        if (permission.value.includes(cm.id)){
          menu.checkedChildren?.push(cm.id);
        }
      }
    }
  }
}

defineExpose({
  elFormRef,
  getFormData: methods.getFormData,
  getCheckedMenu
})
</script>

<template>
  <Form :rules="rules" @register="register">
    <template #permission>
      <div class="w-full">
        <ElCollapse>
          <ElCollapseItem v-for="menu in menuData" :key="menu.id" :title="menu.name">
            <template #title>
              <ElCheckbox v-model="menu.checked"
                :indeterminate="menu.checkedChildren ? menu.checkedChildren.length > 0 && (menu.checkedChildren.length < (menu.children ? menu.children.length : 0)) : false"
                @change="() => handleParentCheckedChange(menu)">{{ menu.name }}</ElCheckbox>
            </template>
            <el-checkbox-group v-model="menu.checkedChildren" @change="() => { handleChildrenChanged(menu) }">
              <el-checkbox v-for="cm in menu.children" :key="`${cm.id}`" :label="cm.id">
                {{ cm.name }}
              </el-checkbox>
            </el-checkbox-group>
          </ElCollapseItem>
        </ElCollapse>
      </div>
    </template>
  </Form>
</template>
